#include "Forker.h"
#include <iostream>


Forker::Forker(const std::string& name) : 
    BaseDriver(name), m_timeInterval(FORK_WORKING_TIME_INTERVAL)
{
    SetEnable(false);
    m_beStop = false;
    m_cond.ResetForVariable();

    m_timeIntervalSpeed = m_speed / m_timeInterval;         // 计算时间间隔内的升叉速度

}

Forker::~Forker()
{
    SetEnable(false);
    m_beStop = true;
    m_cond.NotifyForVariable();
}

bool Forker::Init()
{
    StartTask();        // 启动工作线程
    return true;
}

int Forker::DoTask()
{
    while (!m_beStop)
    {
        if (IsEnable())
        {
            if (m_dir == ForkerDir::FD_NONE) 
            {
                SetEnable(false);
            } 
            else if (m_dir == ForkerDir::FD_UP) 
            {
                if (m_currentHeight >= m_targetHeight)
                {
                    m_currentHeight.store(m_targetHeight);      // 设置成目标高度
                    SetEnable(false);
                }
                m_currentHeight += m_timeIntervalSpeed;
            } 
            else if (m_dir == ForkerDir::FD_DOWN) 
            {    
                if (m_currentHeight <= m_targetHeight)
                {
                    m_currentHeight.store(m_targetHeight);
                    SetEnable(false);
                }
                m_currentHeight -= m_timeIntervalSpeed;
            }
        }
        m_cond.WaitForVariable(m_timeInterval);
    }

    std::cout << "Forker::DoTask() exit" << std::endl;
    return 0;
}

void Forker::SetEnable(bool enable)
{
    m_enable = enable;
    if (m_enable) 
    {
        m_cond.NotifyForVariable();
    } 
    else 
    {
        m_cond.ResetForVariable();
    }
    std::cout << "Forker::SetEnable . enable:" << m_enable<< std::endl;
}

bool Forker::IsEnable()
{
    return m_enable;
}

void Forker::SetTargetHeight(ushort height)
{
    m_targetHeight = height;
    if (m_currentHeight == m_targetHeight) 
    {
        m_dir = ForkerDir::FD_NONE;
    } 
    else if (m_currentHeight < m_targetHeight) 
    {
        m_dir = ForkerDir::FD_UP;
    } 
    else 
    {
        m_dir = ForkerDir::FD_DOWN;
    }
    std::cout << "Forker::SetTargetHeight. targetHeight:" << m_targetHeight << std::endl;
}

ushort Forker::GetCurrentHeight()
{
    return m_currentHeight;
}

ushort Forker::GetTargetHeight()
{
    return m_targetHeight;
}

bool Forker::GetUpIO()
{
    if (m_currentHeight >= FORKER_MAX_HEIGHT)
    {
        return true;
    }
    return false;
}   

bool Forker::GetDownIO()
{
    if (m_currentHeight <= FORKER_MIN_HEIGHT)
    {
        return true;
    }
    return false;
}

void Forker::SetSpeed(int speed)
{
    m_speed = speed;
    m_timeIntervalSpeed = m_speed / m_timeInterval;
    std::cout << "Forker::SetSpeed. speed:" << m_speed << 
        ", timeIntervalSpeed:" << m_timeIntervalSpeed << std::endl;
}

int Forker::GetSpeed()
{
    return m_speed;
}

void Forker::SetTimeInterval(int timeInterval)
{
    m_timeInterval = timeInterval;
    m_timeIntervalSpeed = m_speed / m_timeInterval;
    std::cout << "Forker::SetTimeInterval. timeInterval:" << m_timeInterval << 
        ", timeIntervalSpeed:" << m_timeIntervalSpeed << std::endl;
}

